package controller

import (
	"errors"
	"github.com/gin-gonic/gin"
	"github.com/yourusername/book-management-system/internal/service"
	"github.com/yourusername/book-management-system/pkg/dto"
	"github.com/yourusername/book-management-system/pkg/response"
	"net/http"
	"strconv"
)

type BookController struct {
	bookService service.BookService
}

func NewBookController(bs service.BookService) *BookController {
	return &BookController{bookService: bs}
}

func (c *BookController) CreateBook(ctx *gin.Context) {
	var bookDto dto.BookCreateDTO
	if err := ctx.ShouldBindJSON(&bookDto); err != nil {
		response.BadRequest(ctx, err)
		return
	}

	book, err := c.bookService.CreateBook(bookDto)
	if err != nil {
		response.Error(ctx, err)
		return
	}

	response.Success(ctx, book)
}

func (c *BookController) GetBook(ctx *gin.Context) {
	id, err := strconv.ParseUint(ctx.Param("id"), 10, 32)
	if err != nil {
		response.BadRequest(ctx, err)
		return
	}

	book, err := c.bookService.GetBookByID(uint(id))
	if err != nil {
		response.Error(ctx, err)
		return
	}

	response.Success(ctx, book)
}

func (c *BookController) UpdateBook(ctx *gin.Context) {
	id, err := strconv.ParseUint(ctx.Param("id"), 10, 32)
	if err != nil {
		response.BadRequest(ctx, err)
		return
	}

	var bookDto dto.BookUpdateDTO
	if err := ctx.ShouldBindJSON(&bookDto); err != nil {
		response.BadRequest(ctx, err)
		return
	}

	book, err := c.bookService.UpdateBook(uint(id), bookDto)
	if err != nil {
		response.Error(ctx, err)
		return
	}

	response.Success(ctx, book)
}

func (c *BookController) DeleteBook(ctx *gin.Context) {
	id, err := strconv.ParseUint(ctx.Param("id"), 10, 32)
	if err != nil {
		response.BadRequest(ctx, err)
		return
	}

	if err := c.bookService.DeleteBook(uint(id)); err != nil {
		response.Error(ctx, err)
		return
	}

	response.Success(ctx, nil)
}

func (c *BookController) ListBooks(ctx *gin.Context) {
	page, _ := strconv.Atoi(ctx.DefaultQuery("page", "1"))
	pageSize, _ := strconv.Atoi(ctx.DefaultQuery("pageSize", "10"))

	books, total, err := c.bookService.ListBooks(page, pageSize)
	if err != nil {
		response.Error(ctx, err)
		return
	}

	response.SuccessWithPagination(ctx, books, page, pageSize, total)
}

func (c *BookController) SearchBooks(ctx *gin.Context) {
	query := ctx.Query("q")
	if query == "" {
		response.BadRequest(ctx, errors.New("search query is required"))
		return
	}

	page, _ := strconv.Atoi(ctx.DefaultQuery("page", "1"))
	pageSize, _ := strconv.Atoi(ctx.DefaultQuery("pageSize", "10"))

	books, total, err := c.bookService.SearchBooks(query, page, pageSize)
	if err != nil {
		response.Error(ctx, err)
		return
	}

	response.SuccessWithPagination(ctx, books, page, pageSize, total)
}

func (c *BookController) BorrowBook(ctx *gin.Context) {
	// 从JWT中获取用户ID (简化实现)
	userID := uint(1) // 实际应从认证信息中获取

	bookID, err := strconv.ParseUint(ctx.Param("id"), 10, 32)
	if err != nil {
		response.BadRequest(ctx, err)
		return
	}

	if err := c.bookService.BorrowBook(userID, uint(bookID)); err != nil {
		response.Error(ctx, err)
		return
	}

	response.Success(ctx, gin.H{"message": "book borrowed successfully"})
}

func (c *BookController) ReturnBook(ctx *gin.Context) {
	bookID, err := strconv.ParseUint(ctx.Param("id"), 10, 32)
	if err != nil {
		response.BadRequest(ctx, err)
		return
	}

	if err := c.bookService.ReturnBook(uint(bookID)); err != nil {
		response.Error(ctx, err)
		return
	}

	response.Success(ctx, gin.H{"message": "book returned successfully"})
}
